<template>
  <div>
      <!-- 树 -->
      <ul :id="treeId" class="ztree"></ul>
      <!-- 右键弹窗插槽 -->
      <div ref="rightMenu" v-show="isShowRightMenu" class="treeRightMenu" @click="clickRightMenu($event)">
          <slot name="right-menu" v-bind:node="rightSelectedNode"></slot>
      </div>
  </div>
</template>

<script>
  export default {
    props: {
        treeId: String,
        nodes: Array,
        setting: Object,
        enableRightMenu: Boolean, // 是否开启右键菜单
        searchKey: String, // 用来查询关键字
        searchField: String, // 节点用来查询的字段名称
        searchResultHide: Boolean, // 是否隐藏不符合条件的节点：true-隐藏，false-不隐藏
        editEnable: Boolean// 是否开启编辑功能（优先级高于setting中的配置）
    },
    data: function () {
        return {
            rightSelectedNode: {}, // 右键选中节点
            isShowRightMenu: false, // 是否显示右键弹出菜单
            createNum: 0, // 新建节点数
            hasUpdate: false, // 树节点是否有数据更新
            treeObj: null,
            isLoading: false// 是否正在加载
        }
    },
    created: function () {
        // console.log('c-tree组件created >>>', this.treeId);
        // 是否开启右键菜单
        if (this.enableRightMenu === true) {
            this.setting.callback.onRightClick = this.showRightMenu;
        }
    },
    mounted: function () {
        // this.initTreeObj();
    },
    methods: {
        initTreeObj() {
          this.isLoading = true;
          this.createNum = 0;
          if (this.getTreeObj() !== null) {
              this.getTreeObj().destroy();
          }
          var treeObj = $.fn.zTree.init($('#' + this.treeId), this.setting, this.nodes);
          // 配置是否可以编辑，以带过来的editEnable为主
          treeObj.setEditable(this.editEnable);
          // 默认展开第一个root节点
          if (treeObj.getNodes().length === 1) {
              treeObj.expandNode(treeObj.getNodes()[0], true);
          }
          this.treeObj = treeObj;
          this.isLoading = false;
          return treeObj;
        },
        // 同步
        getSyncTreeObj() {
          while(this.isLoading === false) {
            return this.treeObj;
          }
        },
        getTreeObj() {
          return this.treeObj;
        },
        getRightMenu(event, treeId, treeNode) {
            this.rightSelectedNode = treeNode;
            return this.$refs.rightMenu;
        },
        showRightMenu(event, treeId, treeNode) {
            // 是否开启编辑功能
            if (!this.editEnable) return false;
            var rightMenu = this.getRightMenu(event, treeId, treeNode);
            // 定位x,y轴
            var coordinate = this.getMouseXY(event);
            // console.log("右键坐标：",coordinate);
            $(rightMenu).css({
                top: coordinate.y + 'px',
                left: coordinate.x + 'px'
            });
            $('body').bind('mousedown', this.onBodyMouseDown);
            //this.getTreeObj().selectNode(treeNode);
            this.isShowRightMenu = true;
        },
        hideRightMenu() {
            $('body').unbind('mousedown', this.onBodyMouseDown);
            this.isShowRightMenu = false;
        },
        onBodyMouseDown(event) {
            if ($(event.target).parents('.treeRightMenu').length === 0) {
                this.hideRightMenu();
            }
        },
        clickRightMenu: function (event) {
            if (event.target.tagName !== 'LI') return;
            var action = event.target.getAttribute('action');
            // console.log("clickRightMenu", action);
            if (action != null) {
                if (action.indexOf('(') === -1) action += '()';
                eval('this.' + action);
            }
            this.hideRightMenu();
        },
        //* ******************************************************
        //* ************点击鼠标右键菜单，触发相关操作***************
        add(isParent = false, name, index, isEditName) {
            var treeObj = this.getTreeObj();
            if (index === undefined) {
                index = this.rightSelectedNode.getIndex() + 1;
            }
            if (isEditName === undefined) {
                isEditName = true;
            }
            var addNodes = treeObj.addNodes(this.rightSelectedNode.getParentNode(), index, this._createNode(name, isParent));
            var addNode = addNodes[0];
            treeObj.selectNode(addNode);
            if (isEditName) {
                treeObj.editName(addNode);
            }
            return addNode;
        },
        addChild(isParent = false, name, index = 0, isEditName) {
            if (isEditName === undefined) {
                isEditName = true;
            }
            var treeObj = this.getTreeObj();
            var addNodes = treeObj.addNodes(
                this.rightSelectedNode, index, this._createNode(name, isParent));
            var addNode = addNodes[0];
            treeObj.selectNode(addNode);
            if (isEditName) {
                treeObj.editName(addNode);
            }
            return addNode;
        },
        remove() {
            TreeTool.removeNode(this.treeId, this.rightSelectedNode);
        },
        editName() {
            var treeObj = this.getTreeObj();
            treeObj.editName(this.rightSelectedNode);
        },
        _createNode(name, isParent) {
            if (name === undefined || name == null) {
                this.createNum++;
                name = (isParent ? '新增目录' : '新增节点') + '_' + this.createNum;
            }
            var node = {};
            node[this.getTreeObj().setting.data.key.name] = name;
            node[this.getTreeObj().setting.data.key.title] = name;
            node[this.getTreeObj().setting.data.simpleData.idKey] = this._createId();
            node.isParent = isParent;
            return node;
        },
        _createId() {
            return uuid(10, 16);
        },
        //* *************end************

        // 获取鼠标坐标XY
        getMouseXY(ev) {
            var x = ev.clientX, y = ev.clientY;
            y += document.body.scrollTop;
            x += document.body.scrollLeft;
            return {x: x, y: y};
        }
    },
    watch: {
        nodes: function (newVal, oldVal) {
            // console.log('侦听到', this.treeId, '树的nodes来源发生改变，销毁并重新初始化树对象：', oldVal.length, '>>>', newVal.length);
            this.initTreeObj();
        },
        searchKey: function (newVal, oldVal) {
            // 延迟0.3秒若值还未改变就查询
            var $this = this;
            var timer = window.setTimeout(function () {
                if ($this.searchKey == newVal) {
                    TreeTool.filter($this.treeId, newVal, $this.searchField, $this.searchResultHide);
                }
                clearTimeout(timer);
            }, 300);
        },
        editEnable: function (newVal, oldVal) {
            // console.log("侦听到树编辑功能改变：", newVal);
            this.getTreeObj().setEditable(newVal);
        }
    }
  }
</script>

<style type="text/css">
.treeRightMenu {
  position: fixed;
  visibility: visible;
  top: 0;
  background-color: #f9f9f9;
  text-align: left;
  z-index: 99999;
}
.treeRightMenu ul {
  margin: 0px;
  padding: 0px;
  border: 1px solid #dedede;
}
.treeRightMenu ul li {
  padding: 5px 20px;
  cursor: pointer;
  border-bottom: 1px solid #dedede;
  list-style: none;
  font-size: 12px;
}
.treeRightMenu ul li:last-child{
  border-bottom: none;
}
.treeRightMenu ul li:hover {
  background-color: #ffebc0;
}
.dataTree li a input.rename {
  height: auto !important;
  width: auto !important;
  padding: 0 6px 0 3px !important;
  margin: 0 -6px 0 0 !important;
  font-size: 14px !important;
  border: 1px #585956 solid !important;
}
</style>
